package org.jeecg.modules.system.controller;


import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.jeecg.common.api.vo.Result;
import org.keycloak.admin.client.CreatedResponseUtil;
import org.keycloak.admin.client.Keycloak;
import org.keycloak.admin.client.resource.GroupResource;
import org.keycloak.admin.client.resource.GroupsResource;
import org.keycloak.admin.client.resource.UserResource;
import org.keycloak.representations.idm.CredentialRepresentation;
import org.keycloak.representations.idm.GroupRepresentation;
import org.keycloak.representations.idm.UserRepresentation;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.ws.rs.core.Response;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;

/**
 * <p>
 * 用户表 前端控制器
 * </p>
 *
 * @Author scott
 * @since 2018-12-20
 */
@Slf4j
@RestController
@RequestMapping("/keycloak")
public class KeyCloakController {

    @Value("${keycloak.resource}")
    private String keycloakClient;

    @Value("${keycloak.auth-server-url}")
    private String keycloakUrl;

    @Value("${keycloak.realm}")
    private String keycloakRealm;

    @Value("${keycloak.admin.user:admin}")
    private String keycloakAdminUser;

    @Value("${keycloak.admin.password:123456}")
    private String keycloakAdminPassword;

    Keycloak getKeycloakInstance() {
        return Keycloak.getInstance(
                keycloakUrl,
                "master",
                keycloakAdminUser,
                keycloakAdminPassword,
                "admin-cli");
    }

    @GetMapping("/adduser")
    public Result addUser(String username, String realname, String password, String groups) {
        Keycloak keycloak = getKeycloakInstance();
        UserRepresentation userRepresentation = new UserRepresentation();
        userRepresentation.setUsername(username);
        userRepresentation.setFirstName(realname);
        userRepresentation.setEnabled(true);

        CredentialRepresentation credentialRepresentation = new CredentialRepresentation();
        credentialRepresentation.setType(CredentialRepresentation.PASSWORD);
        credentialRepresentation.setValue(password);
        credentialRepresentation.setTemporary(false);
        userRepresentation.setCredentials(Arrays.asList(credentialRepresentation));
        Response response = keycloak.realm(keycloakRealm).users().create(userRepresentation);
        String userId = CreatedResponseUtil.getCreatedId(response);

        UserResource userResource = keycloak.realm(keycloakRealm).users().get(userId);

        userResource.joinGroup("8e780a67-c027-46b6-a320-afdaa1c9587d");

//        if (CollectionUtils.isNotEmpty(groups)) {
//            groups.forEach(gid -> {
//                userResource.joinGroup(gid);
//            });
//        }

        return Result.OK(response.getStatusInfo().getReasonPhrase() + "  " + userId);
    }

    @GetMapping("/getuser")
    public Result getUser(String userid) {
        Keycloak keycloak = getKeycloakInstance();
        UserResource userResource = keycloak.realm(keycloakRealm).users().get(userid);
        List<GroupRepresentation> groupRepresentationList = userResource.groups();

        UserRepresentation userRepresentation = userResource.toRepresentation();
        return Result.OK(userRepresentation);
    }

    @GetMapping("/updateuser")
    public Result updateUser(String userid, String realname, @RequestParam("groups") List<String> groups) {
        Keycloak keycloak = getKeycloakInstance();
        UserRepresentation userRepresentation = keycloak.realm(keycloakRealm).users().get(userid).toRepresentation();

        userRepresentation.setFirstName(realname);
        userRepresentation.setEnabled(true);
        UserResource userResource = keycloak.realm(keycloakRealm).users().get(userid);
        userResource.update(userRepresentation);
        List<GroupRepresentation> oldGroups = keycloak.realm(keycloakRealm).users().get(userid).groups();
        if (CollectionUtils.isNotEmpty(oldGroups)) {
            oldGroups.forEach(oldGroup -> {
                userResource.leaveGroup(oldGroup.getId());
            });
        }
        if (CollectionUtils.isNotEmpty(groups)) {
            groups.forEach(gid -> {
                userResource.joinGroup(gid);
            });
        }
        return Result.OK();
    }

    @GetMapping("/deluser")
    public Result deleteUser(String userid) {
        Keycloak keycloak = getKeycloakInstance();
        keycloak.realm(keycloakRealm).users().delete(userid);
        return Result.OK();
    }

    @GetMapping("/addgroup")
    public Result addGroup(String parentId, String groupCode, String groupName) {
        String groupId = "";
        Keycloak keycloak = getKeycloakInstance();
        if (StringUtils.isNotBlank(parentId)) {
            GroupRepresentation subgroup = new GroupRepresentation();
            subgroup.setName(groupName);
            subgroup.setAttributes(new HashMap<String, List<String>>() {{
                put("code", new ArrayList<String>() {{
                    add(groupCode);
                }});
            }});
            Response response = keycloak.realm(keycloakRealm).groups().group(parentId).subGroup(subgroup);
            groupId = CreatedResponseUtil.getCreatedId(response);
        } else {
            GroupRepresentation group = new GroupRepresentation();
            group.setName(groupName);
            group.setAttributes(new HashMap<String, List<String>>() {{
                put("code", new ArrayList<String>() {{
                    add(groupCode);
                }});
            }});
            Response response = keycloak.realm(keycloakRealm).groups().add(group);
            groupId = CreatedResponseUtil.getCreatedId(response);
        }
        return Result.OK(groupId);
    }

    @GetMapping("/updategroup")
    public Result updateGroup(String groupId, String groupName, String groupCode) {
        Keycloak keycloak = getKeycloakInstance();
        GroupRepresentation group = new GroupRepresentation();
        group.setId(groupId);
        group.setName(groupName);
        group.setAttributes(new HashMap<String, List<String>>() {{
            put("code", new ArrayList<String>() {{
                add(groupCode);
            }});
        }});
        keycloak.realm(keycloakRealm).groups().group(groupId).update(group);
        return Result.OK();
    }

    @GetMapping("/delgroup")
    public Result delGroup(String groupId) {
        Keycloak keycloak = getKeycloakInstance();
        keycloak.realm(keycloakRealm).groups().group(groupId).remove();
        return Result.OK();
    }

    @GetMapping("/getgroup")
    public Result getGroup(String groupname) {
        Keycloak keycloak = getKeycloakInstance();

        GroupsResource groupsResource = keycloak.realm(keycloakRealm).groups();
        return Result.OK();
    }
}
